﻿using Autofac;
using Autofac.Integration.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.Mvc;

namespace General
{
    public class AutoFacBootStrapper
    {
        /// <summary>
        /// Ioc容器初始化
        /// </summary>
        public static void Register()
        {
            //第一步： 构造一个AutoFac的builder容器  
            var builder = new ContainerBuilder();
            //注册业务层与数据层
            SetupResolveRules(builder);
            //注册Controller层
            builder.RegisterControllers(Assembly.GetExecutingAssembly());
            //第四步：创建一个真正的AutoFac的工作容器  
            var container = builder.Build();
            //第五步：将当前容器中的控制器工厂替换掉MVC默认的控制器工厂。（即：不要MVC默认的控制器工厂了，用AutoFac容器中的控制器工厂替代）此处使用的是将AutoFac工作容器交给MVC底层 (需要using System.Web.Mvc;)  
            DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
        }

        /// <summary>
        /// 以程序集的方式进行依注入
        /// </summary>
        /// <param name="builder"></param>
        private static void SetupResolveRules(ContainerBuilder builder)
        {
            //General只用引用services和repository的接口，不用引用实现的dll。
            //如需加载实现的程序集，将dll拷贝到bin目录下即可，不用引用dll(将dll直接编译到根目录下)
            var iServices = Assembly.Load("General.IServices");
            var services = Assembly.Load("General.Services");
            var iRepository = Assembly.Load("General.IRepository");
            var repository = Assembly.Load("General.Repository");

            //根据名称约定（服务层的接口和实现均以Services结尾），实现服务接口和服务实现的依赖
            builder.RegisterAssemblyTypes(iServices, services).Where(t => t.Name.EndsWith("Services")).AsImplementedInterfaces();

            //根据名称约定（数据访问层的接口和实现均以Repository结尾），实现数据访问接口和数据访问实现的依赖
            builder.RegisterAssemblyTypes(iRepository, repository).Where(t => t.Name.EndsWith("Repository")).AsImplementedInterfaces();
        }
    }
}